#ifndef _CAPAINDICES_HASHEXTENSIBLE_H
#define _CAPAINDICES_HASHEXTENSIBLE_H

/*****************************************************************************
*                     Organización de Datos - 75.06                          *
*                         Cátedra Lic. Servetto                              *
*            Facultad de Ingeniería - Universidad de Buenos Aires            *
******************************************************************************/

#include "../Comun/Archivo.h"

#include "Indices.h"
#include "ArchivoRF.h"
#include "ArchivoRLV.h"
#include "ConexionCapaFisica.h"

#include <list>
#include <math.h>
#include <stdio.h>
#include <sstream>
#include <stdlib.h>

//define el largo de la cadena que indica el offset a cada bucket
#define  ARCH_HASH_LONG_CADENA	4

using namespace std;
using namespace Comun;

namespace CapaIndices
{
	typedef struct {
		long posTablaHash;
		long valorRepresentado;
	} EstructuraTablaHash;

	typedef list<MetadatosAtributo>::iterator IteradorDeMetadatosAtributos;
	typedef list<ClaveValor>::iterator IteradorDeClaveValor;

	// Indice implementado sobre un hashing extensible. Implementa la interfaz IIndice.
	class HashExtensible : public IIndice
	{

	public:
		IArchivo* ArchivoHash;
		IArchivo* ArchivoIndice;
		IArchivo* ArchivoDatos;
		long tamanioBucketBytes;
		long directoryDepth;
	        char* organizacionReg;
	        TipoIndice tipoIndice;
		long* tablaHash; //la tabla de direccionamiento a los buckets. El archivo Hash en memoria


		HashExtensible(MetadatosIndice* metadata);

		// Crea un nuevo Indice a partir de la metadata suministrada.
		bool Crear();

		// Inserta 'clave' en el inidce.
		void InsertarClave(Clave* clave);

		// Busca el registro representado por 'clave' y le asigna sus campos.
		void BuscarClave(Clave* clave);

		// Elimina el registro representado por 'clave'
		void EliminarClave(Clave* clave);

		// Actualiza los cambios producidos al registro representado por 'clave'
		void ActualizarClave(Clave* clave);

		~HashExtensible();

		long funcionHash(unsigned char* input, int cantBytes, long mod);

		string IntToString(int i);
		string IntToString(long i);

		Clave* ObtenerClavesPorGrupo(Grupo grupo, bool soloClaves, int *cantClaves);
	};

/*	class ArchivoTemp: public IArchivo{

		public:
			ArchivoTemp(string nombre, MetadatosArchivo& metadatosDelArchivo);
			ArchivoTemp(string nombre);
			~ArchivoTemp(){}

			int CrearGrupo(Grupo &grupo){return 0;}
		    CodigoResultado GuardarGrupo(Grupo &grupo, bool omitirSubflujo = false){return Exito;}
			Grupo& LeerGrupo(int grupoId){return *actual;}
			void BorrarGrupo(int grupoId){return;}
			int PrimerGrupo(){return 0;}
			int SiguienteGrupo(int grupoIdActual){return 0;}
			Grupo* actual;
			void Crear(){}

		private:
			list<Grupo>* grupos;
			//Nodo* nodos; nodo deriva de grupo
			int lastId;
		};
*/
}



#endif
